package com.meshnetics.gb.stack.mac.primitives;

import com.meshnetics.gb.stack.core.event.StackEventType;
import com.meshnetics.gb.stack.core.event.StackRequest;
import com.meshnetics.gb.stack.mac.RadioMACStackLayer;
import com.meshnetics.gb.stack.mac.type.DisassociationReason;
import com.meshnetics.gb.type.impl.ByteUtils;
import com.meshnetics.gb.type.impl.zcl.Bool;
import com.meshnetics.gb.type.impl.zcl.TypeBool;
import com.meshnetics.gb.type.impl.zcl.TypeUInt;
import com.meshnetics.gb.type.impl.zcl.UInt;

import java.nio.ByteBuffer;

/**
 * WRITE DESCRIPTION HERE
 *
 * @author AKovylin
 */
public class MACDisassociateRequest extends StackRequest implements MACCommand, MACReplyAwaited {
    public static final byte CODE = 0x49;

    private final UInt deviceAddress;
    private final DisassociationReason disassocReason;
    private final Bool securityEnable;

    public MACDisassociateRequest(long deviceAddress, DisassociationReason disassocReason, boolean securityEnable) {
        this(new Long(deviceAddress), disassocReason, Boolean.valueOf(securityEnable));
    }

    public MACDisassociateRequest(Long deviceAddress, DisassociationReason disassocReason, Boolean securityEnable) {
        this((UInt) TypeUInt.UINT_64.fromObject(deviceAddress), disassocReason,
                (Bool) TypeBool.BOOLEAN.fromObject(securityEnable));
    }

    public MACDisassociateRequest(UInt deviceAddress, DisassociationReason disassocReason, Bool securityEnable) {
        super("macDisassociateRequest", StackEventType.LME_TYPE);
        if (deviceAddress == null) {
            throw new NullPointerException("deviceAddress is null");
        }
        if (disassocReason == null) {
            throw new NullPointerException("disassocReason is null");
        }
        if (securityEnable == null) {
            throw new NullPointerException("securityEnable is null");
        }
        if (securityEnable.isInvalid()) {
            throw new IllegalArgumentException("invalid securityEnable");
        }
        this.deviceAddress = deviceAddress.convert(TypeUInt.UINT_64);
        this.disassocReason = disassocReason;
        this.securityEnable = securityEnable;
    }

    public UInt getDeviceAddressType() {
        return deviceAddress;
    }

    public Long getDeviceAddress() {
        return (Long) deviceAddress.toObject();
    }

    public DisassociationReason getDisassocReason() {
        return disassocReason;
    }

    public Bool getSecurityEnableType() {
        return securityEnable;
    }

    public Boolean getSecurityEnable() {
        return (Boolean) securityEnable.toObject();
    }

    public byte getCode() {
        return CODE;
    }

    public int getSize(RadioMACStackLayer layer) {
        return 10;
    }

    public void serialize(ByteBuffer bb, RadioMACStackLayer layer) {
        ByteUtils.ensureNotNull(bb);
        deviceAddress.serialize(bb);
        disassocReason.serialize(bb);
        securityEnable.serialize(bb);
    }

    public String toString() {
        return getName() + '(' + deviceAddress + ',' + disassocReason + ',' + securityEnable + ')';
    }
}
